<?php
/**
 * Created by PhpStorm.
 * User: zhengze
 * Date: 2019/7/1
 * Time: 18:29
 */

namespace app\index\logic;

use app\common\exception\ExceptionEmun;

use app\common\exception\UserException;
use Helper\ArrayHelper;
use app\common\model\Member;
use app\common\model\MemberAccess;
use app\common\model\MemberGroupRelation;
use app\common\logic\BaseLogic;
use app\common\token\token;
use app\common\traits\InstanceTrait;
use app\common\event\IndexLogin;
use app\common\validate\MemberValidate;
use think\facade\Db;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\exception\DbException;
use think\model\Collection;

/**
 * Class MemberLogic
 * @package app\admin\logic
 */
class MemberLogic extends BaseLogic
{
    use InstanceTrait;

    /**
     * @return \app\common\model\base\BaseModel|false|null
     * @throws \app\common\exception\BaseException
     */
    public function login()
    {
        $Member = Member::instance();
        $userInfo = MemberValidate::instance()->getTempMember();
        if ($userInfo['status'] === 0) {
            ExceptionEmun::throwException(UserException::LOCKED);
            return false;
        }
        // 获取菜单和权限
        $member_id = $userInfo[$Member->getPk()];
        event(IndexLogin::class,$member_id);
        return $userInfo;
    }

    /**
     * 获取菜单和权限
     * @param $member_info
     * @return null | Array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getMenuList($member_info)
    {
        $menusList = [];
        if (!empty($member_info)) {
            $member_info->groups->load('menus');
            $menusList = ArrayHelper::arrayColumnMerge($member_info['groups'], 'menus');
            $menusList = array_unique($menusList);
            $menusList = Collection::make($menusList)->toArray();
            //处理菜单成树状
            $menusList = ArrayHelper::arrayToTree($menusList, 'menu_id', 'pid', 'child', 0, true, array('pid'));
        }
        return $menusList;
    }

    /**
     * 根据uid返回用户信息(权限，菜单，用户信息),
     * 用于获取正在登录用户和已经登录用户的信息
     * @param $uid
     * @return bool
     * @throws app\common\exception\BaseException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function getMore($uid)
    {
        $Member = Member::instance();
        $userInfo = $Member->getById($uid);
        $dataList = $Member->getMenuList($userInfo);
        if (empty($dataList['menusList'])) {
            ExceptionEmun::throwException(UserException::NO_RIGHT);
            return false;
        }
        $data['userInfo'] = $userInfo;
        $data['menusList'] = $dataList['menusList'];
        return $data;
    }

    /**
     * JWT生成token
     * @param $userinfo ,可以传member_id
     * @return array
     */
    public function createJwt($userinfo)
    {
        if (!empty($userinfo) && is_int($userinfo)) {
            $userinfo = Member::instance()->getByID($userinfo);
        }
        $userinfo['model'] = Member::class;
        $Token = Token::instance();
        $token = $Token->generateToken($userinfo);
        return $token;
    }

    /**
     * [getDataList 列表]
     * @AuthorHTL
     * @DateTime  2017-02-10T22:19:57+0800
     * @param $keywords
     * @param $page
     * @param $limit
     * @return mixed [array]                             [description]
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws DbException
     * @noinspection UnsupportedStringOffsetOperationsInspection
     */
    public function getDataList($param)
    {
        $Member = Member::instance();
        $where = $Member->getBaseWhere($param);
//      除去超级管理员s
//      $where[] = ['user.'.$Member->getPk(), '<>', '1'];
        $dataCount = $Member->alias('user')
                           ->where($where)
                           ->count('*');
        $param['page'] = !empty($param['page']) ? $param['page'] : 1;
        $param['limit'] = !empty($param['limit']) ? $param['limit'] : 15;
        $list = $Member
            ->where($where)
            ->alias('user')
            ->page($param['page'], $param['limit'])
            ->field($Member->baseField)
            ->select();
        $list->hidden(['password']);
        if (false === $list->isEmpty()) {
            $list->load(['post','structure']);
        }

        $data['list'] = $list;
        $data['dataCount'] = $dataCount;

        return $data;
    }

    /**
     * @param $param
     */
    public function read($member_id)
    {
        $Member = Member::instance();
        $member = $Member->getByID($member_id);
        if (empty($member)) {
            ExceptionEmun::throwException(UserException::NO_EXIST);
        }
        $member->hidden(['password']);
        return $member;
    }

    /**
     * MemberAccess中间表写入
     * @param $group_id
     * @param $member_id
     * @param $menus
     */
    protected function insertGroupRelation($member_id, $groups)
    {
        $groups = ArrayHelper::ToTree($groups);
        $data = MemberGroupRelation::beforeInsertData([ 'member_id' => $member_id]);
        $insertAllDate = [];
        foreach ($groups as $key => $value) {
            $insertAllDate[$key] = $data;
            $insertAllDate[$key]['group_id'] = $value;
        }
        Db::table(MemberGroupRelation::instance()->getTable())->insertAll($insertAllDate);
    }

    /**
     * 创建用户
     * @param array $param [description]
     */
    public function createData($param)
    {
        // 验证
        Member::instance()->startTrans();
        $param['phone'] = 0;
        $param['password'] = encrypt_password($param['password']);
        $Member = Member::create($param);
//        太慢,废除
//        $Member->groups()->saveAll($param['groups']);
        $this->insertGroupRelation($Member['member_id'], $param['groups']);
        Member::instance()->commit();
        return true;
    }


    /**
     * 通过id修改用户
     * @param array $param [description]
     */
    public function updateByID($param)
    {
        $Member = Member::instance();
        $id = $param[$Member->getPk()] ?? $param['id'];
        $Member->startTrans();
        // 只有超级管理员能操作超级管理员
        if (1 === (int)$id && 1 !== (int)Token::instance()->getUserInfo()[$Member->getPk()]) {
            ExceptionEmun::throwException(UserException::$update_member);
        }
        $member = Member::field($Member->baseField)->where('member_id', '=', $id)->find();
        if (!$member) {
            ExceptionEmun::throwException(UserException::NO_EXIST);
        }
        $member->groups()->detach();
//        太慢,废除
//        $member->groups()->saveAll($param['groups']);
        $this->insertGroupRelation($id, $param['groups']);
        //填了密码就加密,不填就不该密码
        if (!empty($param['password'])) {
            $param['password'] = encrypt_password($param['password']);
        } else {
            unset($param['password']);
        }
        $member->save($param);
        $Member->commit();
        return true;

    }
}
